#ifndef _RENDER_INTERFACE_H
#define _RENDER_INTERFACE_H

#include "stdafx.h"
#include "RenderResource.h"
#include "light.h"
#include "JPEGParser.h"

#if defined(WIN32) && !defined(_CONSOLE)
#include "glsl.h"
#endif

enum DecoCullMode
{
	CM_CW,
	CM_CCW,
	CM_None
};

// Transform types.

enum DecoTransformType
{
	TT_LocalToWorld,
	TT_WorldToCamera,
	TT_CameraToScreen,
	TT_Max
};


// Primitive types for DrawPrimitive.

enum DecoPrimitiveType
{
	PT_TriangleList,
	PT_TriangleStrip,
	PT_TriangleFan,
	PT_PointList,
	PT_LineList,
	PT_LineLoop,
	PT_LineStrip,
	PT_Max
};

enum DecoDrawType
{
	DT_WireFrame,
	DT_SolidPolygon,
	DT_FrontPolygon,
	DT_BackPolygon,
	DT_Max
};

enum DecoRenderState
{
	RS_ModelMatrix,
	RS_ViewMatrix,
	RS_ProjectionMatrix,
	RS_CullMode,
	RS_ViewPort,
	RS_Color,
	RS_DepthTest,
	RS_Texture,
	RS_RenderType,
	RS_LogicOp,
	RS_StencilState,
	RS_All
};

enum DecoRenderType
{
	RT_Opaque,
	RT_Transparent,
	RT_Masked,
	RT_Reflection
};

enum DecoLogicOp
{
	LO_NoOp,
	LO_Xor
};

enum DecoColorChannel
{
	CC_R,
	CC_G,
	CC_B,
	CC_A,
	CC_RGB,
	CC_RGBA
};
 enum DecoBufferType
 {
	 BT_Front,
	 BT_Back
 };

 enum DecoStencilState
 {
	SS_Accumulate,
	SS_Deduct,
	SS_Test,
	SS_None
 };

class DecoRenderInterface;
class DecoRenderData
{
public:
	DecoRenderData()
	{
	}
	virtual ~DecoRenderData() {}
	virtual Box GetBoundingBox() = 0;
	virtual Box	GetUntransformedBoundingBox() const = 0;
	virtual void SetLocalToWorld(const matrix44& matrix) = 0;
	virtual void RenderBoundingBox(DecoRenderInterface* RI) = 0;
	virtual BOOL RayIntersection(const vector3& origin, const vector3& dir, vector3& intersectionPt, DOUBLE& time, vector3* normal = NULL) = 0;
	virtual BOOL NeedSort() = 0;
	virtual void Render(DecoRenderInterface* RI, DecoLight** Lights = NULL, INT numLight = 0, DecoDrawType DrawType = DT_SolidPolygon) = 0;
	virtual void RenderTransparentSection(DecoRenderInterface* RI, DecoLight** Lights = NULL, INT numLight = 0, DecoDrawType DrawType = DT_SolidPolygon) = 0;
	virtual void RenderOpaqueSection(DecoRenderInterface* RI, DecoLight** Lights = NULL, INT numLight = 0, DecoDrawType DrawType = DT_SolidPolygon) = 0;
	virtual VOID Scale(DOUBLE xcoef, DOUBLE ycoef, DOUBLE zcoef) = 0;
	virtual int RayIntersectionCount(const vector3& origin, const vector3& dir) = 0;
	virtual BOOL IsPrimitiveInBox(Box& box) = 0;
	virtual void RetrieveAllVertices(vector<vector3>& allVertices) = 0;
	virtual BOOL IsPointInside(const vector3& pt, bool bVote = false) = 0;
	virtual void DumpToObjFile(const string& fileName) = 0;
};


class DecoRenderInterface
{
#if defined(WIN32) && !defined(_CONSOLE)
public:
	glShader* shader;
	glShaderManager SM;

#endif

public:

	virtual ~DecoRenderInterface() {}

	virtual void Initialize() = 0;
	virtual void Destroy() = 0;
	virtual void PushState(DecoRenderState State = RS_All) = 0;
	virtual void PopState(DecoRenderState State = RS_All) = 0;

	//virtual BOOL SetRenderTarget(FRenderTarget* RenderTarget) = 0;
	virtual void SetViewport(INT X,INT Y,INT Width,INT Height) = 0;
	virtual void GetViewport(INT& X, INT& Y, INT &Width, INT& Height) = 0;
	virtual void Clear(BOOL UseColor = 1, DecoColor color = DecoColor(60,60,255),BOOL UseDepth = 1,FLOAT Depth = 1.0f, BOOL UseStencil = 1, INT Stencil = 0) = 0;

	virtual void SetCullMode(DecoCullMode CullMode) = 0;

	virtual void SetAmbientLight(const DecoColor& AmbColor) = 0;
	virtual void SetLight(INT LightIndex, const DecoLight* light) = 0;
	virtual void ResetLight() = 0;
	virtual void EnableDepthTest(BOOL bEnable) = 0;
	virtual void EnableTexture(BOOL bEnable) = 0;

	virtual void EnablePxLogicOp(DecoLogicOp op) = 0;

	virtual void SetTransform(DecoTransformType Type, matrix44& Matrix) = 0;
	virtual void GetTransform(DecoTransformType Type, matrix44& Matrix) = 0;
	virtual void SetMaterial(const DecoMaterial& material) = 0;
	virtual void SetColor(const DecoColor& color) = 0;
	virtual void SetStencilState(DecoStencilState state) = 0;
	virtual void DrawPrimitive(DecoPrimitiveType PrimitiveType, size_t NumPrimitives, DecoDrawType DrawType, DecoVertexBuffer* VB, DecoIndexBuffer* IB = NULL) = 0;
	virtual void BeginRenderType(DecoRenderType type) = 0;
	virtual void EndRenderType() = 0;
	virtual void SetReflectionConstraint(DecoRenderData* constraint) = 0;
	virtual void SaveToImage(const char * filename, DecoBufferType type = BT_Back) = 0;
	virtual void SetLineWidth(FLOAT n) = 0;
	virtual void ReadFrameBuffer(DecoBufferType buffType, DecoColorChannel ch, void* pixels) = 0;
	virtual void WriteFrameBuffer(INT x, INT y, INT wid, INT ht, DecoBufferType buffType, DecoColorChannel ch, void* pixels) = 0;
};
#endif